package no.ntnu.idi.deid.patternmatching.search.dictionary.medicalcodes;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeSet;


import no.ntnu.idi.deid.config.FilePaths;
import no.ntnu.idi.deid.documentunits.Token;
import no.ntnu.idi.deid.searchresultunits.CategoryTag;
import no.ntnu.idi.deid.searchresultunits.Tag;

/*
 * 
 * ATC kodene er hentet fra FEST - Statens Legemiddelverk
 * 
 * http://www.legemiddelverket.no/Bruk_og_raad/FEST/nedlasting-av-fest/Sider/default.aspx
 * 
 * Dette er en veldig stor XML-fil med alle typer medikamenter + relasjoner mellom disse. 
 * Vi har kun hentet ut kode --> virkestoff + NavnFormStyrke
 * 
 * Hvert unike par av ATC-kode:Virkestoff mapper til en liste med medikamenter, derfor instansieres kodene slik:
 * 
 * HashMap<KODE, HashMap<VIRKESTOFF,TreeSet<MEDIKAMENTER>>>
 * 
 */

public class ATC_Codes {
	
	private Map<String, HashMap<String,TreeSet<String>>> ATCCodes;
	
	private static ATC_Codes instance = null;

	private ATC_Codes() {
		try {
			readAndMakeATCCodes();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//Returnerer en CategoryTag enten hvis Token t er en ATC-kode eller et virkestoff 
	public static CategoryTag searchATC(Token t) {
		if(instance == null) {
			instance = new ATC_Codes();
		}
		if(instance.getATCNameByCode(t)!=null){
			return new CategoryTag(Tag.ATC,t.getStripped(),instance.getATCNameByCode(t));
		}
		else if(instance.getATCCodeByName(t)!=null){
			return new CategoryTag(Tag.ATC,instance.getATCCodeByName(t),t.getStripped());
		}
		return null;
	}
	
	/**
	 * 
	 * @param code
	 * @return virkestoff if the code exists, else null
	 */
	private String getATCNameByCode(Token t) {
		if(ATCCodes.containsKey(t.getStripped())){
			HashMap<String, TreeSet<String>> map = ATCCodes.get(t.getStripped());
			Iterator<Entry<String, TreeSet<String>>> es = map.entrySet().iterator();
			Entry<String, TreeSet<String>> element = es.next();
			return (element.getKey());
		}
		return null;
	}
	
	private String getATCCodeByName(Token t){
		Iterator<Entry<String, HashMap<String, TreeSet<String>>>> it = ATCCodes.entrySet().iterator(); 
		while(it.hasNext()){
			Entry<String, HashMap<String, TreeSet<String>>> entry = (Entry<String, HashMap<String, TreeSet<String>>>) it.next();
			String atcCode = entry.getKey();
			HashMap<String, TreeSet<String>> map = entry.getValue();
			if(map.containsKey(t.getStripped())){
				return atcCode;
			}
		}
		return null;
	}
	
	private void readAndMakeATCCodes() throws FileNotFoundException{
		ATCCodes = new HashMap<String, HashMap<String,TreeSet<String>>>();
		Scanner sc = new Scanner(new File(FilePaths.getATCCodesFilePath()));
		while(sc.hasNext()){
			String[] line = sc.nextLine().trim().split(" \\$\\$\\$ ");
			if(line.length>1){handleLine(line);}
		}
		sc.close();
	}
	
	private void handleLine(String[] line){
		String code = line[0].trim();
		if(ATCCodes.containsKey(code)){
			ATCCodes.get(code).get(line[1].trim()).add(line[2].trim());
		}
		else{
			TreeSet<String> list = new TreeSet<String>();
			HashMap<String, TreeSet<String>> map = new HashMap<String, TreeSet<String>>();
			list.add(line[2].trim());
			map.put(line[1].trim(), list);
			ATCCodes.put(line[0], map);
		}
		
	}

//	public static void main(String[] args) throws FileNotFoundException{
//		Token t = new Token(4454, "Ibuprofen");
//		System.out.println(searchATC(t));
		
		
		
//		*************KODE for å mekke ATC fila**********************
//		ArrayList<String> sortedCodes = new ArrayList<String>();
//		int ccc = 0;
//		Iterator<Entry<String, HashMap<String, TreeSet<String>>>> ittt = ATCCodes.entrySet().iterator();
//		while(ittt.hasNext()){
//			ccc++;
//			Map.Entry<String, ArrayList<String>> entry =  (Map.Entry)ittt.next();
//			sortedCodes.add(entry.getKey());
//		}
//		
//		System.out.println("ccc: " + ccc);
//		Collections.sort(sortedCodes);
//		int counter = 0;
//		for(String s: sortedCodes){
//			System.out.println(s);
//			HashMap<String, TreeSet<String>> m = ATCCodes.get(s);
//			Iterator ite = m.entrySet().iterator();
//			while (ite.hasNext()){
//				Map.Entry ent =  (Map.Entry)ite.next();
//				System.out.println("--"+ent.getKey());
//				TreeSet<String> str = (TreeSet<String>) ent.getValue();
//				for(String string: str){
//					counter++;
//					System.out.println("-----"+string);
//				}
//			}
//		}
//	}
			
		
//		
//		Iterator<Entry<String, HashMap<String, ArrayList<String>>>> it = ATCCodes.entrySet().iterator();
//		while(it.hasNext()){
//			Map.Entry en =  (Map.Entry)it.next();
//			System.out.println(en.getKey());
//			HashMap<String, ArrayList<String>> m = (HashMap<String, ArrayList<String>>) en.getValue();
//			Iterator ite = m.entrySet().iterator();
//			while (ite.hasNext()){
//				counter++;
//				Map.Entry ent =  (Map.Entry)ite.next();
//				System.out.println("--"+ent.getKey());
//				ArrayList<String> str = (ArrayList<String>) ent.getValue();
//				for(String string: str){
//					counter++;
//					System.out.println("-----"+string);
//				}
//			}
//		}
//	}
	
//	}
	
//	ArrayList<String> sortedCodes = new ArrayList<String>();
//	int ccc = 0;
//	Iterator<Entry<String, HashMap<String, TreeSet<String>>>> ittt = ATC_Codes.getInstance().ATCCodes.entrySet().iterator();
//	while(ittt.hasNext()){
//		ccc++;
//		Map.Entry<String, HashMap<String,TreeSet<String>>> entry=  (Map.Entry)ittt.next();
//		HashMap<String,TreeSet<String>> hash = entry.getValue();
//		Iterator<Entry<String,TreeSet<String>>> it = hash.entrySet().iterator();
//		while(it.hasNext()) {
//			Map.Entry<String,TreeSet<String>> entry2 = (Map.Entry)it.next();
//			System.out.println(entry2.getKey());
//			TreeSet<String> ts = entry2.getValue();
//			Iterator<String> it3 = ts.iterator();
//			while(it3.hasNext()) {
//				String str = it3.next();
//				System.out.println(str);
//			}
//			
//		}
////		TreeSet<String> set = hash.entrySet()
////		System.out.println(hash);
//	}
	
}
